﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Windows.Storage;

namespace TextNovelReader.Services;

public class Settings
{
    private readonly ApplicationDataContainer _localSettings;
    private readonly Dictionary<string, object> _defaultSettings = new()
    {
        ["FontSize"] = 20.0,
        ["WhiteLines"] = 1,
        ["FilePath"] = string.Empty,
        ["ScrollSpeed"] = 200,
        ["ThemeIndex"] = 0,
        ["ChapterIndex"] = 0,
        ["FontName"] = "Font_SimHei"
    };

    public Settings()
    {
        _localSettings = ApplicationData.Current.LocalSettings;
        InitializeLocalSettings();
    }

    // Events
    public event Action<string>? FilePathChanged;
    public event Action<double>? FontSizeChanged;
    public event Action<int>? WhiteLinesChanged;
    public event Action<int>? ThemeIndexChanged;
    public event Action<string>? FontNameChanged;

    // Properties
    public double FontSize
    {
        get => GetProperty<double>();
        set => SetProperty(value, FontSizeChanged); 
    }

    public int WhiteLines
    {
        get => GetProperty<int>();
        set => SetProperty(value, WhiteLinesChanged);
    }

    public string FilePath
    {
        get => GetProperty<string>();
        set => SetProperty(value, FilePathChanged);
    }

    public int ScrollSpeed
    {
        get => GetProperty<int>();
        set => SetProperty(value);
    }

    public int ThemeIndex
    {
        get => GetProperty<int>();
        set => SetProperty(value, ThemeIndexChanged);
    }

    public int ChapterIndex
    {
        get => GetProperty<int>();
        set => SetProperty(value);
    }

    public string FontName
    {
        get => GetProperty<string>();
        set => SetProperty(value, FontNameChanged); 
    }

    public void InitializeLocalSettings()
    {
        if (_localSettings.Values.Count == _defaultSettings.Count)
            return;

        _localSettings.Values.Clear(); 
        foreach (var (key, value) in _defaultSettings)
        {
            _localSettings.Values[key] = value;
        }
    }

    private T GetProperty<T>([CallerMemberName] string? propertyName = null)
    {
        return (T)_localSettings.Values[propertyName];
    }

    private void SetProperty<T>(T value, Action<T>? propertyChanged = null, [CallerMemberName] string? propertyName = null)
        where T : IComparable<T>
    {
        var oldValue = (T)_localSettings.Values[propertyName];
        if (oldValue.CompareTo(value) == 0)
        {
            return; 
        }
        _localSettings.Values[propertyName] = value;
        propertyChanged?.Invoke(value); 
    }
}
